package com.ruoyi.business.utils;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.business.domain.BuyerInfo;
import com.ruoyi.business.domain.GoodsInfo;
import com.ruoyi.business.vo.*;
import com.ruoyi.common.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.*;

/**
 * @author ty
 */

@Service
@RequiredArgsConstructor
@Slf4j
public class WeimobUtil {

    private final StringRedisTemplate redisTemplate;

    private final String CLIENT_ID = "CB3FFC01C40B662386DA3A190C4087F7";
    private final String CLIENT_SECRET = "E756DA9183B1BDDE9E7B8480500C419A";
    private final String REDIS_KEY = "weimob:access_token";

    private final RestTemplate restTemplate;


    /**
     * 获取 AccessToken，带 Redis 缓存和自动续期
     */
    public String getAccessToken() {
        // 先查缓存
        String token = redisTemplate.opsForValue().get(REDIS_KEY);
        if (token != null) {
            return token;
        }

        // 请求地址
        String url = String.format(
                "https://dopen.weimob.com/fuwu/b/oauth2/token?grant_type=client_credentials&client_id=%s&client_secret=%s",
                CLIENT_ID, CLIENT_SECRET);

        // 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<String> httpEntity = new HttpEntity<>(null, headers);

        try {
            ResponseEntity<JSONObject> response = restTemplate.exchange(
                    url, HttpMethod.POST, httpEntity, JSONObject.class);

            JSONObject body = response.getBody();
            if (body != null && body.containsKey("access_token")) {
                String accessToken = body.getString("access_token");
                int expiresIn = body.getIntValue("expires_in");

                // 缓存 token（设置过期时间略小于实际，以避免边界问题）
                redisTemplate.opsForValue().set(REDIS_KEY, accessToken, Duration.ofSeconds(expiresIn - 60));
                return accessToken;
            } else {
                throw new RuntimeException("获取 access_token 失败: 响应为空或格式异常");
            }
        } catch (Exception e) {
            throw new RuntimeException("请求 access_token 失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取客户基础信息
     *
     * @param widList
     * @return
     */
    public List<BuyerInfo> fetchFromWeimob(List<Long> widList) {
        if (CollectionUtils.isEmpty(widList)) {
            throw new BadRequestException("客户编号不能为空!");
        }
        String accessToken = this.getAccessToken();
        String url = "https://dopen.weimob.com/apigw/weimob_crm/v2.0/customer/getList?accesstoken=" + accessToken;

        JSONObject param = new JSONObject();
        //需要查询的客户编号 wid 列表,最大支持一次查询 20 条
        param.put("widList", widList);
        param.put("resultType", Arrays.asList(1));

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> httpEntity = new HttpEntity<>(param.toJSONString(), headers);
        ResponseEntity<JSONObject> response = restTemplate.exchange(
                url, HttpMethod.POST, httpEntity, JSONObject.class
        );

        JSONObject body = response.getBody();
        List<BuyerInfo> resultList = new ArrayList<>();

        if (body != null && "0".equals(body.getByPath("code.errcode"))) {
            JSONArray buyerArray = JSONUtil.parseArray(body.getByPath("data.userBaseInfoList"));
            for (int i = 0; i < buyerArray.size(); i++) {
                cn.hutool.json.JSONObject buyer = buyerArray.getJSONObject(i);
                BuyerInfo buyerInfo = new BuyerInfo();
                buyerInfo.setWid(buyer.getLong("wid"));
                buyerInfo.setUserNickName(buyer.getStr("nickname"));
                buyerInfo.setName(buyer.getStr("name"));
                buyerInfo.setPhone(buyer.getStr("phone"));
                resultList.add(buyerInfo);
            }
        }
        return resultList;
    }

    /*
    从微盟获取商品详情接口
    */
    public List<GoodsInfo> selectGoodListfetchFromWeimob(Long goodsId) throws Exception {
        if (goodsId == null) {
            throw new MyException("商品ID不能为空");
        }
        String accessToken = this.getAccessToken();
        String url = "https://dopen.weimob.com/apigw/weimob_shop/v2.0/goods/get?accesstoken=" + accessToken;
        HashMap<String, Object> basicInfo = new HashMap<>();
        basicInfo.put("vid", "6017037364631");
        // 构建完整请求参数
        Map<String, Object> requestParams = new HashMap<>();
        requestParams.put("accesstoken", accessToken);
        requestParams.put("goodsId", goodsId.toString());
        requestParams.put("basicInfo", basicInfo);
        // 发送请求  如果请求失效，hash值为0
        String response = sendPostRequest(url, requestParams);
        // 解析响应
        ArrayList<GoodsInfo> goodsInfos = new ArrayList<>();
        com.alibaba.fastjson2.JSONArray goodsArray = JSON.parseObject(response).getJSONArray("data");
        com.alibaba.fastjson2.JSONArray errmsg = JSON.parseObject(response).getJSONArray("code");
        if (goodsArray == null || goodsArray.isEmpty()) {
            throw new MyException(errmsg.getJSONObject(0).getString(("errmsg")));
        }
        for (int i = 0; i < goodsArray.size(); i++) {
            JSONObject item = goodsArray.getJSONObject(i);
            com.alibaba.fastjson2.JSONArray skuListArray = item.getJSONArray("skuList");
            com.alibaba.fastjson2.JSONArray categoryJson = item.getJSONArray("categoryList");
            Long categoryId = categoryJson.getJSONObject(0).getLong("categoryId");
            if (skuListArray == null || skuListArray.isEmpty()) {
                continue;
            }
            // 4. 将JSON转换为goodsInfo对象
            Long goodsArrayId = item.getLong("goodsId");
            String title = item.getString("title");
            for (int j = 0; j < skuListArray.size(); j++) {
                GoodsInfo goodsInfo = new GoodsInfo();
                //拿到当前对象
                JSONObject skuJson = skuListArray.getJSONObject(j);
                goodsInfo.setGoodsId(goodsArrayId);
                //商品名称
                goodsInfo.setTitle(title);
                //商品数量
                goodsInfo.setSkuNum(skuJson.getLong("skuStockNum"));
                //规格条码
                goodsInfo.setSkuBarCode(skuJson.getString("skuBarCode"));
                //商品销售价格
                goodsInfo.setSalePrice(skuJson.getBigDecimal("salePrice"));
                //商品规格编码
                goodsInfo.setSkuCode(skuJson.getString("outerSkuCode"));
                //skuId
                goodsInfo.setSkuId(skuJson.getLong("skuId"));
                //
                // 获取skuSpecValueJson
                com.alibaba.fastjson2.JSONArray skuSpecValueJson = skuJson.getJSONArray("skuSpecValueList");

                // 检查childrenJson是否存在且至少有两条数据
                if (skuSpecValueJson != null && skuSpecValueJson.size() == 1) {
                    // 获取第一条和第二条数据的specValueName
                    String firstSpec = skuSpecValueJson.getJSONObject(0).getString("specValueName");
                    goodsInfo.setSpecValueName(firstSpec);
                } else if (skuSpecValueJson != null && skuSpecValueJson.size() > 1) {
                    // 获取第一条和第二条数据的specValueName
                    String firstSpec = skuSpecValueJson.getJSONObject(0).getString("specValueName");
                    String secondSpec = skuSpecValueJson.getJSONObject(1).getString("specValueName");
                    // 拼接两个specValueName
                    String specValueName = new StringBuilder().append(firstSpec).append("-").append(secondSpec).toString();
                    //规格名称
                    goodsInfo.setSpecValueName(specValueName);
                } else {
                    // 如果不符合条件，添加默认值
                    goodsInfo.setSpecValueName(" ");
                }
                goodsInfo.setCategoryId(categoryId);
                goodsInfo.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
                goodsInfo.setStatus(0f);
                // 5. 添加到批量新增列表
                goodsInfos.add(goodsInfo);
            }
        }
        return goodsInfos;
    }


    /*发送请求接口
     * */
    public String sendPostRequest(String url, Map<String, Object> params) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        // 设置请求头
        httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
        // 设置请求体
        StringEntity entity = new StringEntity(JSON.toJSONString(params), StandardCharsets.UTF_8);
        httpPost.setEntity(entity);
        // 执行请求
        HttpResponse response = httpClient.execute(httpPost);
        return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
    }

    /**
     * 外部订单导入
     *
     * @param sendOrderInfoVo
     * @return
     */
    public boolean sendOrderInfoToWeimob(SendOrderInfoVo sendOrderInfoVo) {
        if (ObjectUtils.isEmpty(sendOrderInfoVo)) {
            throw new BadRequestException("外部订单导入对象不能为空！");
        }
        String accessToken = this.getAccessToken();
        String url = "https://dopen.weimob.com/apigw/weimob_shop/v2.0/order/omni/import?accesstoken=" + accessToken;

        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("orderInfo", sendOrderInfoVo);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestMap, headers);

        ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.POST, entity, Map.class);

        if (response.getStatusCode() == HttpStatus.OK) {
            Map<String, Object> body = response.getBody();
            if (body != null && "0".equals(((Map) body.get("code")).get("errcode"))) {
                return true;
            } else {
                throw new BadRequestException("推送订单失败,响应" + body);
            }
        }else {
            throw new BadRequestException("推送订单失败，请求状态异常：" + response.getStatusCode());
        }
    }

    /**
     * 外部订单更新
     * 取消
     * @param cancelOrderInfoVo
     * @return
     */
    public boolean sendCancelInfoToWeimob(CancelOrderInfoVo cancelOrderInfoVo) {
        if (ObjectUtils.isEmpty(cancelOrderInfoVo)) {
            throw new BadRequestException("取消信息不能为空！");
        }
        String accessToken = this.getAccessToken();
        String url = "https://dopen.weimob.com/apigw/weimob_shop/v2.0/order/omni/update?accesstoken=" + accessToken;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<CancelOrderInfoVo> entity = new HttpEntity<>(cancelOrderInfoVo, headers);
        ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.POST, entity, Map.class);

        if (response.getStatusCode() == HttpStatus.OK) {
            Map<String, Object> body = response.getBody();
            if (body != null && "0".equals(((Map) body.get("code")).get("errcode"))) {
                return true;
            } else {
                throw new BadRequestException("订单取消 失败,响应" + body);
            }
        } else {
            throw new BadRequestException("订单取消失败，请求状态异常：" + response.getStatusCode());
        }
    }

    /**
     * 外部订单更新
     * 发货
     * @param sendLogisticsVo
     * @return
     */
    public boolean sendMroLogisticsToWeimob(SendLogisticsVo sendLogisticsVo) {
        if (ObjectUtils.isEmpty(sendLogisticsVo)) {
            throw new BadRequestException("发货信息不能为空！");
        }
        String accessToken = this.getAccessToken();
        String url = "https://dopen.weimob.com/apigw/weimob_shop/v2.0/order/omni/update?accesstoken=" + accessToken;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<SendLogisticsVo> entity = new HttpEntity<>(sendLogisticsVo, headers);
        ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.POST, entity, Map.class);

        if (response.getStatusCode() == HttpStatus.OK) {
            Map<String, Object> body = response.getBody();
            if (body != null && "0".equals(((Map) body.get("code")).get("errcode"))) {
                return true;
            } else {
                throw new BadRequestException("订单发货 失败,响应" + body);
            }
        } else {
            throw new BadRequestException("订单发货失败，请求状态异常：" + response.getStatusCode());
        }
    }


    /**
     * 外部订单更新
     * 完成
     * @param sendFinishStatusVo
     * @return
     */
    public boolean sendFinishStatusToWeimob(SendFinishStatusVo sendFinishStatusVo) {
        if (ObjectUtils.isEmpty(sendFinishStatusVo)) {
            throw new BadRequestException("订单完成信息 不能为空！");
        }
        String accessToken = this.getAccessToken();
        String url = "https://dopen.weimob.com/apigw/weimob_shop/v2.0/order/omni/update?accesstoken=" + accessToken;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<SendFinishStatusVo> entity = new HttpEntity<>(sendFinishStatusVo, headers);
        ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.POST, entity, Map.class);

        if (response.getStatusCode() == HttpStatus.OK) {
            Map<String, Object> body = response.getBody();
            if (body != null && "0".equals(((Map) body.get("code")).get("errcode"))) {
                return true;
            } else {
                throw new BadRequestException("订单完成 失败,响应" + body);
            }
        } else {
            throw new BadRequestException("订单完成 失败，请求状态异常：" + response.getStatusCode());
        }
    }

    /**
     * 调整积分
     * @param adjustPointVo
     * @return
     */
    public boolean adjustPointToWeimob(AdjustPointVo adjustPointVo) {
        if (ObjectUtils.isEmpty(adjustPointVo)) {
            throw new BadRequestException("调整积分信息 不能为空！");
        }
        String accessToken = this.getAccessToken();
        String url = "https://dopen.weimob.com/apigw/weimob_crm/v2.0/point/adjust?accesstoken=" + accessToken;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<AdjustPointVo> entity = new HttpEntity<>(adjustPointVo, headers);
        ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.POST, entity, Map.class);

        if (response.getStatusCode() == HttpStatus.OK) {
            Map<String, Object> body = response.getBody();
            if (body != null && "0".equals(((Map) body.get("code")).get("errcode"))) {
                return true;
            } else {
                throw new BadRequestException("调整积分失败,响应" + body);
            }
        } else {
            throw new BadRequestException("调整积分失败，请求状态异常：" + response.getStatusCode());
        }
    }


    /**
     * 获取微盟订单编号
     * @param searchOrderInfoVo
     * @return orderNo 微盟订单编号
     */
    public Long searchOrderInfoFromWeimob(SearchOrderInfoVo searchOrderInfoVo) {
        if (ObjectUtils.isEmpty(searchOrderInfoVo)) {
            throw new BadRequestException("查询微盟订单信息 不能为空！");
        }
        String accessToken = this.getAccessToken();
        String url = "https://dopen.weimob.com/apigw/weimob_shop/v2.0/order/list/search?accesstoken=" + accessToken;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<SearchOrderInfoVo> entity = new HttpEntity<>(searchOrderInfoVo, headers);
        ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.POST, entity, Map.class);

        if (response.getStatusCode() == HttpStatus.OK) {
            Map<String, Object> body = response.getBody();
            if (body != null && "0".equals(((Map) body.get("code")).get("errcode"))) {
                // 解析数据获取 orderNo
                Map<String, Object> data = (Map<String, Object>) body.get("data");
                if (data != null) {
                    List<Map<String, Object>> pageList = (List<Map<String, Object>>) data.get("pageList");
                    if (pageList != null && !pageList.isEmpty()) {
                        Map<String, Object> orderInfoWrapper = pageList.get(0);
                        Map<String, Object> orderInfo = (Map<String, Object>) orderInfoWrapper.get("orderInfo");
                        if (orderInfo != null) {
                            Map<String, Object> orderBaseInfo = (Map<String, Object>) orderInfo.get("orderBaseInfo");
                            if (orderBaseInfo != null) {
                                Object orderNoObj = orderBaseInfo.get("orderNo");
                                if (orderNoObj != null) {
                                    return Long.valueOf(orderNoObj.toString());
                                }
                            }
                        }
                    }
                }
                return null;
            } else {
                throw new BadRequestException("查询微盟订单信息 失败,响应" + body);
            }
        } else {
            throw new BadRequestException("查询微盟订单信息 失败，请求状态异常：" + response.getStatusCode());
        }
    }

    /**
     * 外部订单更新
     * 推送支付信息
     * @param updateOrderPayInfoVo
     * @return
     */
    public boolean sendPayInfoToWeimob(UpdateOrderPayInfoVo updateOrderPayInfoVo) {
        if (ObjectUtils.isEmpty(updateOrderPayInfoVo)) {
            throw new BadRequestException("支付信息 不能为空！");
        }
        String accessToken = this.getAccessToken();
        String url = "https://dopen.weimob.com/apigw/weimob_shop/v2.0/order/omni/update?accesstoken=" + accessToken;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<UpdateOrderPayInfoVo> entity = new HttpEntity<>(updateOrderPayInfoVo, headers);
        ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.POST, entity, Map.class);

        if (response.getStatusCode() == HttpStatus.OK) {
            Map<String, Object> body = response.getBody();
            if (body != null && "0".equals(((Map) body.get("code")).get("errcode"))) {
                return true;
            } else {
                throw new BadRequestException("订单支付信息更新失败,响应" + body);
            }
        } else {
            throw new BadRequestException("订单支付信息更新失败，请求状态异常：" + response.getStatusCode());
        }
    }
}